from rest_framework.response import Response
from rest_framework import status
from rest_framework.viewsets import ModelViewSet
from django.http import StreamingHttpResponse
from django.utils.encoding import escape_uri_path

from equity_admin.serializers_goods import *
from equity_mall.utils.pages import MyPage
from equity_mall.utils.utils import get_level_list
from equity_admin.tasks import *


class GoodsTagActivityModelViewSet(ModelViewSet):

    queryset = GoodsTagActivity.objects.all()
    serializer_class = GoodsTagActivityModelSerializer
    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('activity_name', )
    filter_class = GoodsTagActivityFilter

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        level_id = self.request.data.get('level_id', None)
        goods_tag = self.request.data.get('goods_tag', None)
        activity_name = self.request.data.get('activity_name', None)
        if not all([level_id, goods_tag, activity_name]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            level = Level.objects.get(id=level_id)
        except:
            return Response({'error': '无效层级id'}, status=status.HTTP_400_BAD_REQUEST)
        data = {}
        data['level_id'] = level_id
        data['goods_tag'] = goods_tag
        data['activity_name'] = activity_name
        data['create_user_id'] = user.id
        instance = GoodsTagActivity.objects.create(**data)
        return Response({'success': '添加成功', 'goods_tag_activity_id': instance.id}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.activity_state == 1:
            instance.activity_state = 2
            instance.save()
        else:
            instance.activity_state = 1
            instance.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def goods_tag_allocation_level(self, request):
        goods_tag_activity_id = self.request.query_params.get('goods_tag_activity_id', None)
        search = self.request.query_params.get('search', None)
        if not goods_tag_activity_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            activity = self.get_queryset().get(id=goods_tag_activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level = activity.level
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        queryset = queryset.exclude(goodstagactivitylevelrelation__goods_tag_activity_id=goods_tag_activity_id)
        if search:
            queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = LevelListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = LevelListSerializer(queryset, many=True)
        return Response(serializer.data)

    def goods_tag_allocation(self, request):
        user = self.request.iser
        data_array = self.request.data.get('data_array', None)
        goods_tag_activity_id = self.request.data.get('goods_tag_activity_id', None)
        try:
            instance = self.get_queryset().get(id=goods_tag_activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level_list = get_level_list(instance.level)
        if not data_array:
            return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                for level_id in data_array:
                    if int(level_id) not in level_list:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                    diacountcouponlevel_data = {}
                    diacountcouponlevel_data['level_id'] = level_id
                    diacountcouponlevel_data['goods_tag_activity_id'] = goods_tag_activity_id
                    diacountcouponlevel, create = GoodsTagActivityLevelRelation.objects.get_or_create(goods_tag_activity_id=goods_tag_activity_id, level_id=level_id, defaults=diacountcouponlevel_data)
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '分配成功'}, status=status.HTTP_200_OK)


class GoodsTagActivityLevelRelationModelViewSet(ModelViewSet):

    queryset = GoodsTagActivityLevelRelation.objects.all()
    serializer_class = GoodsTagActivityLevelRelationModelSerializer
    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = GoodsTagActivityLevelRelationFilter

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.delete()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class LaunchedGoodsModelViewSet(ModelViewSet):
    '''商品'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'goods__merchant__name', 'level__account', 'level__name')
    filter_class = LaunchedGoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return LaunchedGoodsListModelSerializer
        else:
            return LaunchedGoodsListModelSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = LaunchedGoods.objects.all()
        elif level.level == 1:
            queryset = LaunchedGoods.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = LaunchedGoods.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = LaunchedGoods.objects.filter(level__district_id=level.id)
        else:
            queryset = LaunchedGoods.objects.filter(level__branch_id=level.id)
        goods_id = self.request.query_params.get('goods_id', None)
        if goods_id:
            goods = Goods.objects.filter(id=goods_id).first()
            if goods:
                check_query = queryset.filter(goods_id=goods_id, is_self=1)
                if not check_query:
                    launched_goods_data = {}
                    launched_goods_data['name'] = goods.name
                    launched_goods_data['caption'] = goods.caption
                    launched_goods_data['goods_id'] = goods.id
                    launched_goods_data['category_id'] = goods.category_id
                    launched_goods_data['price'] = goods.price
                    launched_goods_data['point'] = goods.point
                    launched_goods_data['stock'] = goods.stock
                    launched_goods_data['is_launched'] = 0
                    launched_goods_data['create_time'] = datetime.datetime.now()
                    launched_goods_data['is_self'] = 1
                    LaunchedGoods.objects.get_or_create(defaults=launched_goods_data, goods_id=goods.id, is_self=1)
        return queryset.order_by('-is_self', 'id')

    def create(self, request, *args, **kwargs):
        goods_id = self.request.data.get('goods_id', None)
        launchedgoods_array = self.request.data.get('launchedgoods_array', None)
        if not all([goods_id, launchedgoods_array]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(launchedgoods_array, list):
            return Response({'error': '参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                while True:
                    try:
                        goods = Goods.objects.get(id=goods_id)
                    except:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '无效商品id'}, status=status.HTTP_400_BAD_REQUEST)
                    origin_remain_stock = goods.remain_stock
                    count = 0
                    for launchedgoods in launchedgoods_array:
                        launchedgoods_data = {}
                        launchedgoods_data['level_id'] = launchedgoods['level_id']
                        launchedgoods_data['stock'] = launchedgoods['stock']
                        launchedgoods_data['goods_id'] = goods_id
                        launchedgoods_data['create_time'] = datetime.datetime.now()
                        launchedgoods_data['price'] = goods.price
                        launchedgoods_data['category_id'] = goods.category_id
                        instance, create = LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=launchedgoods_data['level_id'], goods_id=goods_id)
                        if create:
                            count += int(launchedgoods['stock'])
                    new_remain_stock = origin_remain_stock + count
                    result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock)
                    if result == 0:
                        continue
                    break
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '上架成失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        stock = self.request.data.get('stock', None)
        if not stock:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            stock = int(stock)
        except:
            return Response({'error': '库存参数格式有误, 请输入整数型'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                if instance.is_self == 0:
                    while True:
                        instance = LaunchedGoods.objects.get(id=instance.id)
                        goods = Goods.objects.get(id=instance.goods_id)
                        origin_remain_stock = goods.remain_stock
                        launched_origin_stock = instance.stock
                        change_stock = launched_origin_stock - stock
                        new_remain_stock = origin_remain_stock - change_stock
                        launched_result = LaunchedGoods.objects.filter(id=instance.id, stock=launched_origin_stock).update(stock=stock)
                        result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock)
                        if result == 0:
                            continue
                        if launched_result == 0:
                            continue
                        break
                else:
                    while True:
                        instance = LaunchedGoods.objects.get(id=instance.id)
                        goods = Goods.objects.get(id=instance.goods_id)
                        origin_remain_stock = goods.remain_stock
                        origin_stock = goods.stock
                        launched_origin_stock = instance.stock
                        change_stock = launched_origin_stock - stock
                        new_remain_stock = origin_remain_stock - change_stock
                        new_stock = origin_stock - change_stock
                        launched_result = LaunchedGoods.objects.filter(id=instance.id, stock=launched_origin_stock).update(stock=stock)
                        result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock, stock=new_stock)
                        if result == 0:
                            continue
                        if launched_result == 0:
                            continue
                        break
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '修改成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        is_launched = self.request.data.get('is_launched', None)
        if not is_launched:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) not in ['0', '1']:
            return Response({'error': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) == '0':
            instance.is_launched = 0
            instance.save()
            return Response({'success': '下架成功'}, status=status.HTTP_200_OK)
        else:
            instance.is_launched = 1
            instance.save()
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)


class GoodsCategoryModelViewSet(ModelViewSet):

    serializer_class = GoodsCategoryModelSerializer
    queryset = GoodsCategory.objects.all()
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )


class GoodsModelViewSet(ModelViewSet):
    '''商品'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )
    filter_class = GoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return GoodsListModelSerializer
        else:
            return GoodsRetrieveModelSerializer

    def get_serializer_context(self):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        return {"alidiscountcoupon_id": alidiscountcoupon_id}

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        goods_tag_activity_id = self.request.query_params.get('goods_tag_activity_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = Goods.objects.all().order_by('-id')
        elif level.level == 1:
            queryset = Goods.objects.filter(launchedgoods__level__prov_id=level.id).distinct()
        elif level.level == 2:
            queryset = Goods.objects.filter(launchedgoods__level__city_id=level.id).distinct()
        elif level.level == 3:
            queryset = Goods.objects.filter(launchedgoods__level__district_id=level.id).distinct()
        else:
            queryset = Goods.objects.filter(launchedgoods__level__branch_id=level.id).distinct()
        if alidiscountcoupon_id:
            alidiscountcoupon = AliDiscountCoupon.objects.filter(id=alidiscountcoupon_id).first()
            if alidiscountcoupon and alidiscountcoupon.goods_tag:
                queryset = queryset.filter(goods_tag=alidiscountcoupon.goods_tag)
        if goods_tag_activity_id:
            goods_tag_activity = GoodsTagActivity.objects.filter(id=goods_tag_activity_id).first()
            if goods_tag_activity:
                queryset = queryset.filter(goods_tag=goods_tag_activity.goods_tag)
            # filter_goods_id_list = AliDiscountCouponGoodsAvailable.objects.filter(alidiscountcoupon_id=alidiscountcoupon_id).values_list('goods_id', flat=True)
            # if filter_goods_id_list:
            #     queryset = queryset.exclude(id__in=list(filter_goods_id_list))
        return queryset.order_by('-id')

    def upload_image(self, request):
        user = self.request.iser
        img = self.request.FILES.get('img', None)
        merchant_id = self.request.data.get('merchant_id', None)
        if not all([img, merchant_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户号'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/goods_image{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'success': '操作成功', 'img_id': f'https://circle.sutpay.cn/{img_id}'}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        merchant_id = self.request.data.get('merchant_id', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        category_id = self.request.data.get('category_id', None)
        goods_tag = self.request.data.get('goods_tag', None)
        order_type = self.request.data.get('order_type', 1)
        is_group = self.request.data.get('is_group', None)
        group_price = self.request.data.get('group_price', None)
        group_order_num = self.request.data.get('group_order_num', None)
        group_limit_time = self.request.data.get('group_limit_time', None)
        group_limit_type = self.request.data.get('group_limit_type', None)
        proof = self.request.data.get('proof', None)
        desc_pack = self.request.data.get('desc_pack', '')
        if not all([name, caption, desc_detail, price, market_price, default_image, image_array, merchant_id, manufacturer, specifications, category_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except:
            return Response({'error': '无效商品类别参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        goods_data = {}
        if str(is_group) == '1':
            if not all([group_price, group_limit_time, group_order_num, group_limit_type]):
                return Response({'error': '请上传拼团的其他信息'}, status=status.HTTP_400_BAD_REQUEST)
            if str(group_limit_type) not in ['1', '2']:
                return Response({'error': '拼团时限类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                group_price = Decimal(group_price)
                group_limit_time = int(group_limit_time)
            except:
                return Response({'error': '拼团金额时限参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            if group_price <= Decimal('0'):
                return Response({'error': '拼团金额不能小于0'}, status=status.HTTP_400_BAD_REQUEST)
            goods_data['is_group'] = is_group
            goods_data['group_price'] = group_price
            goods_data['group_order_num'] = group_order_num
            goods_data['group_limit_time'] = group_limit_time
            goods_data['group_limit_type'] = group_limit_type
        goods_data['name'] = name
        goods_data['caption'] = caption
        goods_data['desc_detail'] = desc_detail
        goods_data['desc_pack'] = desc_pack
        goods_data['price'] = price
        goods_data['market_price'] = market_price
        goods_data['default_image'] = default_image.replace('https://circle.sutpay.cn/', '')
        goods_data['merchant_id'] = merchant_id
        goods_data['manufacturer'] = manufacturer
        goods_data['specifications'] = specifications
        goods_data['is_launched'] = 1
        goods_data['category_id'] = category_id
        goods_data['goods_tag'] = goods_tag
        goods_data['order_type'] = order_type
        goods_data['longitude'] = merchant.longitude
        goods_data['latitude'] = merchant.latitude
        goods_data['order_species'] = 2
        goods_data['proof'] = proof.replace('https://circle.sutpay.cn/', '')
        area = GoodsAreaCode.objects.filter(district_name=merchant.district_name, prov_name=merchant.prov_name, city_name=merchant.city_name).first()
        if area:
            goods_data['area_id'] = area.id
        try:
            goods = Goods.objects.create(**goods_data)
            for image in image_array:
                GoodsImage.objects.create(
                    goods_id=goods.id,
                    image = image.replace('https://circle.sutpay.cn/', '')
                )
            try:
                GoodsAuditRecord.objects.create(
                    goods_id=goods.id,
                    create_user_id=user.id,
                    audit_type=1,
                    remark="新增商品"
                )
            except:
                pass
            return Response({'success': '创建成功', 'goods_id': goods.id}, status=status.HTTP_200_OK)
        except Exception as e:
            logger.error(str(e))
            return Response({'error': '创建失败.请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        desc_pack = self.request.data.get('desc_pack', '')
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        goods_tag = self.request.data.get('goods_tag', None)
        order_type = self.request.data.get('order_type', None)
        is_group = self.request.data.get('is_group', None)
        group_price = self.request.data.get('group_price', None)
        group_order_num = self.request.data.get('group_order_num', None)
        group_limit_time = self.request.data.get('group_limit_time', None)
        group_limit_type = self.request.data.get('group_limit_type', None)
        proof = self.request.data.get('proof', None)
        if not all([name, caption, desc_detail, price, market_price, default_image, image_array, manufacturer, specifications, proof]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_group) == '1':
            if not all([group_price, group_limit_time, group_order_num, group_limit_type]):
                return Response({'error': '请上传拼团的其他信息'}, status=status.HTTP_400_BAD_REQUEST)
            if str(group_limit_type) not in ['1', '2']:
                return Response({'error': '拼团时限类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                group_price = Decimal(group_price)
                group_limit_time = int(group_limit_time)
            except:
                return Response({'error': '拼团金额时限参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            if group_price <= Decimal('0'):
                return Response({'error': '拼团金额不能小于0'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance.name = name
            instance.caption = caption
            instance.desc_detail = desc_detail
            instance.desc_pack = desc_pack
            instance.price = price
            instance.goods_tag = goods_tag
            instance.market_price = market_price
            instance.default_image = default_image.replace('https://circle.sutpay.cn/', '')
            instance.manufacturer = manufacturer
            instance.specifications = specifications
            instance.is_group = is_group
            instance.group_price = group_price
            instance.group_limit_time = group_limit_time
            instance.group_order_num = group_order_num
            instance.group_limit_type = group_limit_type
            instance.group_limit_type = group_limit_type
            instance.proof = proof.replace('https://circle.sutpay.cn/', '')
            if str(order_type) in ['1', '5', '6']:
                instance.order_type = order_type
            instance.save()
            GoodsImage.objects.filter(goods_id=instance.id).delete()
            for image in image_array:
                GoodsImage.objects.create(
                    goods_id=instance.id,
                    image = image.replace('https://circle.sutpay.cn/', '')
                )
            return Response({'success': '编辑商品成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '编辑商品失败'}, status=status.HTTP_400_BAD_REQUEST)

    def applyment(self, request):
        user = self.request.iser
        applyment_id = self.request.data.get('applyment_id')
        reject_reason = self.request.data.get('reject_reason', None)
        applyment_status = self.request.data.get('applyment_status', None)
        if not applyment_id:
            return Response({'error': '缺少申请单参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(applyment_status) not in ['1', '2']:
            return Response({'error': '审核状态参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            applyment = GoodsModifyApplyment.objects.get(id=applyment_id)
        except:
            return Response({'error': '无效申请单id'}, status=status.HTTP_400_BAD_REQUEST)
        if applyment.applyment_status != 1:
            return Response({'error': '申请单状态有误,请勿重复操作'}, status=status.HTTP_400_BAD_REQUEST)
        goods = applyment.goods
        launched_goods = LaunchedGoods.objects.filter(goods_id=goods.id, level_id=applyment.level_id).first()
        if str(applyment_status) == '2':
            if not reject_reason:
                return Response({'error': '请输入驳回原因'}, status=status.HTTP_400_BAD_REQUEST)
            if applyment.applyment_type == 1:
                applyment.applyment_status = 3
                applyment.reject_reason = reject_reason
                applyment.save()
                goods.is_launched = 3
                if applyment.update_word:
                    update_word = json.loads(applyment.update_word)
                    for word in update_word:
                        if word == 'name':
                            goods.name = applyment.name
                        elif word == 'desc_detail':
                            goods.desc_detail = applyment.desc_detail
                        elif word == 'price':
                            goods.price = applyment.price
                        elif word == 'default_image':
                            default_image = applyment.default_image.__str__()
                            goods.default_image = default_image.replace('https://circle.sutpay.cn', '')
                        elif word == 'manufacturer':
                            goods.manufacturer = applyment.manufacturer
                        elif word == 'specifications':
                            goods.specifications = applyment.specifications
                        elif word == 'market_price':
                            goods.market_price = applyment.market_price
                        elif word == 'caption':
                            goods.caption = applyment.caption
                        elif word == 'goodsimage_set':
                            goodsimage_set = goods.goodsimage_set.all().delete()
                            image_array = json.loads(applyment.image_array)
                            for image in image_array:
                                GoodsImage.objects.create(
                                    goods_id=goods.id,
                                    image=image.replace('https://circle.sutpay.cn/', '')
                                )
                goods.save()
            else:
                applyment.applyment_status = 3
                applyment.reject_reason = reject_reason
                applyment.save()
                goods.is_launched = 3
                goods.save()
            remark = '超级管理员审核商品(驳回)'
        elif str(applyment_status) == '1':
            if applyment.applyment_type == 1:
                applyment.applyment_status = 2
                applyment.save()
                goods.remain_stock = goods.remain_stock + launched_goods.stock - applyment.stock
                goods.is_launched = 1
                goods.save()
            else:
                applyment.applyment_status = 2
                applyment.save()
                goods.remain_stock = goods.remain_stock + launched_goods.stock - applyment.stock
                goods.is_launched = 1
                goods.save()
                merchantenter_set = goods.merchant.merchantenter_set.all()
                for merchantenter in merchantenter_set:
                    launchedgoods_data = {}
                    launchedgoods_data['level_id'] = merchantenter.level_id
                    launchedgoods_data['goods_id'] = goods.id
                    launchedgoods_data['is_launched'] = 0
                    launchedgoods_data['name'] = goods.name
                    launchedgoods_data['category_id'] = 1
                    launchedgoods_data['stock'] = 0
                    LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=merchantenter.level_id, goods_id=goods.id)
            remark = '超级管理员审核商品(通过)'
        else:
            return Response({'error': '审核状态参数有误'}, status=status.HTTP_200_OK)
        try:
            GoodsAuditRecord.objects.create(
                goods_id=goods.id,
                create_user_id=user.id,
                audit_type=2,
                remark=remark
            )
        except:
            pass
        try:
            expedite_applyment_send.delay({'id': applyment.id})
        except:
            pass
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.is_launched not in [0, 1]:
            return Response({'error': '商品状态有误,无法操作'}, status=status.HTTP_400_BAD_REQUEST)
        is_launched = self.request.data.get('is_launched', None)
        if not is_launched:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) not in ['0', '1']:
            return Response({'error': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) == '0':
            instance.is_launched = 0
            instance.save()
            return Response({'success': '下架成功'}, status=status.HTTP_200_OK)
        else:
            instance.is_launched = 1
            instance.save()
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)

    def export_goods(self, request):
        user = self.request.iser
        is_launched = self.request.query_params.get('is_launched', None)
        search = self.request.query_params.get('search', None)
        level = user.level
        if level.level == 0:
            condition = 'WHERE level_id IN (SELECT id FROM tb_u_level)'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        # if search:
        #     condition = condition + f' AND mobile LIKE "%{search}%"'
        if is_launched:
            condition = condition + f' AND is_launched in ({is_launched})'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT e.*,f.category_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.merchant_name,short_name,wyfMerchantID,level_id FROM (SELECT id,equityID,name,category_id,is_launched,merchant_id,price,market_price,sales,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S')  AS create_time FROM tb_goods)AS a LEFT JOIN (SELECT id,name AS merchant_name,short_name,wyfMerchantID,level_id FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id, name AS category_name FROM tb_goods_category)AS f ON e.category_id=f.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT e.*,f.category_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.merchant_name,short_name,wyfMerchantID,level_id FROM (SELECT id,equityID,name,category_id,is_launched,merchant_id,price,market_price,sales,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S')  AS create_time FROM tb_goods)AS a LEFT JOIN (SELECT id,name AS merchant_name,short_name,wyfMerchantID,level_id FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id, name AS category_name FROM tb_goods_category)AS f ON e.category_id=f.id;
            '''
            cursor.execute(sql)
        ziduan = ['商品ID', '权益ID', '商品名称', '商品分类', '商品状态', '所属商户全称', '所属商户简称', '微邮付商户号',
                  '归属市公司', '归属区县', '归属网点', '原价', '结算价格', '销量', '上架时间']
        cols = ['id', 'equityID', 'name', 'category_name', 'is_launched', 'merchant_name', 'short_name', 'wyfMerchantID',
                'city_name', 'district_name', 'branch_name', 'market_price', 'price', 'sales', 'create_time']
        response = StreamingHttpResponse(self.get_goods_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('商品信息.csv'))
        return response

    def get_goods_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            0: '已下架',
            1: '已上架',
            2: '审核中',
            3: '已驳回'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'is_launched':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def pinned(self, request):
        goods_id = self.request.data.get('goods_id', None)
        if not goods_id:
            return Response({'error': '请上传商品id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=goods_id)
        except:
            return Response({'error': '无效商品id'}, status=status.HTTP_200_OK)
        max_sort = Goods.objects.aggregate(Max("sort"))["sort__max"]
        instance.sort = max_sort+1
        instance.save()
        return Response({'success': '置顶成功'}, status=status.HTTP_200_OK)

    def batch_update_goods_stock(self, reqeust):
        update_type = self.request.data.get('update_type', '1')
        goods_id = self.request.data.get('goods_id', None)
        stock = self.request.data.get('stock', None)
        if not str(stock):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            goods = self.get_queryset().get(id=goods_id)
        except:
            return Response({'error': '无效商品id'}, status=status.HTTP_400_BAD_REQUEST)
        stock = int(stock)
        if str(update_type) == '1':
            if int(stock) < 0:
                return Response({'error': '调整库存不得小于0'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            if int(stock) <= 0:
                return Response({'error': '增加库存须大于0'}, status=status.HTTP_400_BAD_REQUEST)
        launchedgoods_set = LaunchedGoods.objects.filter(goods_id=goods_id)
        for launchedgoods in launchedgoods_set:
            launchedgoods_id = launchedgoods.id
            while True:
                launchedgoods = LaunchedGoods.objects.get(id=launchedgoods_id)
                launched_origin_stock = launchedgoods.stock
                if str(update_type) == '1':
                    change_stock = launched_origin_stock - stock
                else:
                    change_stock = -stock
                new_stock = launched_origin_stock - change_stock
                launched_result = LaunchedGoods.objects.filter(id=launchedgoods_id, stock=launched_origin_stock).update(stock=new_stock)
                if launched_result == 0:
                    continue
                break
            while True:
                goods = Goods.objects.get(id=goods_id)
                origin_remain_stock = goods.remain_stock
                origin_stock = goods.stock
                new_remain_stock = origin_remain_stock - change_stock
                new_stock = origin_stock - change_stock
                result = Goods.objects.filter(id=goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock, stock=new_stock)
                if result == 0:
                    continue
                break
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def batch_unbind_goods_tag(self, request):
        goods_id_array = self.request.data.get('goods_id_array', None)
        if not goods_id_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        Goods.objects.filter(id__in=goods_id_array).update(goods_tag=None)
        return Response({'success': '解绑成功'}, status=status.HTTP_200_OK)